<?php
use taobao\AliSms;


/**
 * 字符串截取，支持中文和其他编码
 */
function msubstr($str, $start = 0, $length, $charset = "utf-8", $suffix = true)
{
    if (function_exists("mb_substr"))
        $slice = mb_substr($str, $start, $length, $charset);
    elseif (function_exists('iconv_substr')) {
        $slice = iconv_substr($str, $start, $length, $charset);
        if (false === $slice) {
            $slice = '';
        }
    } else {
        $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all($re[$charset], $str, $match);
        $slice = join("", array_slice($match[0], $start, $length));
    }
    return $suffix ? $slice . '...' : $slice;
}


//发送短信(参数：签名,模板（数组）,模板ID，手机号)
function sms($signname = '', $param = [], $code = '', $phone)
{
    $alisms = new AliSms();
    $result = $alisms->sign($signname)->data($param)->code($code)->send($phone);
    return $result['info'];
}


function xmlStr_to_json($xmldata, $valueTextName, $flag)
{

    // 生成xml解析器
    $xmlparser = xml_parser_create();

    // 设置xml解析器的参数
    // 控制在该 XML 解析器中 大小写折叠（case-folding） 是否有效。其默认值为有效。 这里填写0表示无效
    xml_parser_set_option($xmlparser, XML_OPTION_CASE_FOLDING, 0);

    // 是否略过由白空字符组成的值。 0为false，其他都为true
    xml_parser_set_option($xmlparser, XML_OPTION_SKIP_WHITE, 1);

    // 将xml解析器中的数据生成数据$values, 当然也可以生成index的数组, 请看标准文档
    xml_parse_into_struct($xmlparser, $xmldata, $values);

    // 释放xml解析器
    xml_parser_free($xmlparser);

    // 将每个节点都作为不同的数据，有①是为了后面好拆分
    $flagNum = 0;

    // 中间生成的数组
    $data = array();

    // 最终要生成的数组
    $afterCleanData = array();

    values_to_data($data, $values, $flagNum, $flag, $valueTextName);
    clean_level($data, $flag, $afterCleanData);
    return json_encode($afterCleanData);
}

// 清除中间产生的data数组中的 level 属性
function clean_level($data, $flag, &$afterCleanData)
{
    foreach ($data as $x => $x_value) {
        $text = $flag . "level" . $flag;
        if (is_array($x_value)) {
            $afterCleanData[$x] = array();
            clean_level($data[$x], $flag, $afterCleanData[$x]);
        } else {
            if ($x != $text) {
                $afterCleanData[$x] = $data[$x];
            }
        }
    }
}

// 从xml解析器中的values数组生成中间数组data
function values_to_data(&$data, $values, &$flagNum, $flag, $valueTextName)
{
    foreach ($values as $x => $x_value) {
        $flagNum = $flagNum + 1;
        $flagStr = $flag . $flagNum;
        //	$parentText = ($x_value["tag"]).$flagStr;
        //	echo $parentText."<br/>";
        $parentText = "";
        findParentText($data, $x_value, $parentText, $flag);

        if ($x_value["type"] == "complete" || $x_value["type"] == "open") {
            //	echo $flagNum."<br/>";
            pushNode($data, $x_value, $parentText, $flagStr, $valueTextName, $flag);
        }
    }
}

// 查找父类节点
function findParentText($data, $nowNode, &$parentText, $flag)
{
    foreach ($data as $x => $x_value) {
        if (is_array($x_value)) {
            $text = $flag . "level" . $flag;
            if ($nowNode['level'] > $data[$x][$text]) {
                $parentText = $x;
                // 要不断的遍历下去才能找到最接近nowNode节点的父类
                findParentText($data[$x], $nowNode, $parentText, $flag);
            }
        }
    }
}

// 向新的data数组中插入节点数据
function pushNode(&$data, $nowNode, $parentText, $flagStr, $valueTextName, $flag)
{
    // 因为最开始的时候是没有parentText的
    if ($parentText == null || $parentText == "") {
        $nodeArray = array();
        $text = $flag . "level" . $flag;
        $nodeArray[$text] = $nowNode["level"];
        // 获取节点值
        if (isset($nowNode["value"])) {
            $nodeArray[$valueTextName] = $nowNode["value"];
        }

        // 获取节点属性
        if (isset($nowNode["attributes"]) && is_array($nowNode["attributes"])) {
            foreach ($nowNode["attributes"] as $x1 => $x1_value1) {
                $nodeArray[$x1] = $x1_value1;
            }
        }
        $text = $nowNode["tag"] . $flagStr;
        $data[$text] = $nodeArray;
    } else {
        foreach ($data as $x => $x_value) {
            if ($x == $parentText) {
                $nodeArray = array();
                $text = $flag . "level" . $flag;
                $nodeArray[$text] = $nowNode["level"];
                // 获取节点值
                if (isset($nowNode["value"])) {
                    $nodeArray[$valueTextName] = $nowNode["value"];
                }
                // 获取节点属性
                if (isset($nowNode["attributes"])) {
                    foreach ($nowNode["attributes"] as $x1 => $x1_value1) {
                        $nodeArray[$x1] = $x1_value1;
                    }
                }
                $text = $nowNode["tag"] . $flagStr;
                $data[$x][$text] = $nodeArray;
            } else {
                if (is_array($data[$x])) {
                    pushNode($data[$x], $nowNode, $parentText, $flagStr, $valueTextName, $flag);
                }
            }
        }
    }

}

function xmlToArray($xml, $options = array())
{
    $defaults = array(
        'namespaceSeparator' => ':',//you may want this to be something other than a colon
        'attributePrefix' => '@',   //to distinguish between attributes and nodes with the same name
        'alwaysArray' => array(),   //array of xml tag names which should always become arrays
        'autoArray' => true,        //only create arrays for tags which appear more than once
        'textContent' => '$',       //key used for the text content of elements
        'autoText' => true,         //skip textContent key if node has no attributes or child nodes
        'keySearch' => false,       //optional search and replace on tag and attribute names
        'keyReplace' => false       //replace values for above search values (as passed to str_replace())
    );
    $options = array_merge($defaults, $options);
    $namespaces = $xml->getDocNamespaces();
    $namespaces[''] = null; //add base (empty) namespace

    //get attributes from all namespaces
    $attributesArray = array();
    foreach ($namespaces as $prefix => $namespace) {
        foreach ($xml->attributes($namespace) as $attributeName => $attribute) {
            //replace characters in attribute name
            if ($options['keySearch']) $attributeName =
                str_replace($options['keySearch'], $options['keyReplace'], $attributeName);
            $attributeKey = $options['attributePrefix']
                . ($prefix ? $prefix . $options['namespaceSeparator'] : '')
                . $attributeName;
            $attributesArray[$attributeKey] = (string)$attribute;
        }
    }

    //get child nodes from all namespaces
    $tagsArray = array();
    foreach ($namespaces as $prefix => $namespace) {
        foreach ($xml->children($namespace) as $childXml) {
            //recurse into child nodes
            $childArray = xmlToArray($childXml, $options);
            list($childTagName, $childProperties) = each($childArray);

            //replace characters in tag name
            if ($options['keySearch']) $childTagName =
                str_replace($options['keySearch'], $options['keyReplace'], $childTagName);
            //add namespace prefix, if any
            if ($prefix) $childTagName = $prefix . $options['namespaceSeparator'] . $childTagName;

            if (!isset($tagsArray[$childTagName])) {
                //only entry with this key
                //test if tags of this type should always be arrays, no matter the element count
                $tagsArray[$childTagName] =
                    in_array($childTagName, $options['alwaysArray']) || !$options['autoArray']
                        ? array($childProperties) : $childProperties;
            } elseif (
                is_array($tagsArray[$childTagName]) && array_keys($tagsArray[$childTagName])
                === range(0, count($tagsArray[$childTagName]) - 1)
            ) {
                //key already exists and is integer indexed array
                $tagsArray[$childTagName][] = $childProperties;
            } else {
                //key exists so convert to integer indexed array with previous value in position 0
                $tagsArray[$childTagName] = array($tagsArray[$childTagName], $childProperties);
            }
        }
    }

    //get text content of node
    $textContentArray = array();
    $plainText = trim((string)$xml);
    if ($plainText !== '') $textContentArray[$options['textContent']] = $plainText;

    //stick it all together
    $propertiesArray = !$options['autoText'] || $attributesArray || $tagsArray || ($plainText === '')
        ? array_merge($attributesArray, $tagsArray, $textContentArray) : $plainText;

    //return node as array
    return array(
        $xml->getName() => $propertiesArray
    );
}